package com.sy.simpleegg.util

import ZtlApi.ZtlManager
import android.Manifest
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.net.NetworkInfo
import android.net.wifi.WifiManager
import android.os.Build
import android.telephony.CellInfo
import android.telephony.CellInfoCdma
import android.telephony.CellInfoGsm
import android.telephony.CellInfoLte
import android.telephony.CellInfoWcdma
import android.telephony.SubscriptionManager
import android.telephony.TelephonyManager
import android.util.Log
import android.view.View
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.proembed.service.MyService
import com.sy.simpleegg.constant.BoardType
import com.sy.simpleegg.ext.logFile
import com.sy.logger.Logger
import java.io.BufferedReader
import java.io.DataOutputStream
import java.io.File
import java.io.FileNotFoundException
import java.io.FileReader
import java.io.IOException
import java.io.InputStreamReader
import java.io.LineNumberReader
import java.io.RandomAccessFile
import java.io.Reader
import java.net.Inet4Address
import java.net.NetworkInterface
import java.net.SocketException
import java.nio.charset.Charset


@SuppressLint("StaticFieldLeak")
object BoardApiUtil {

    private var mContext: Context? = null

    private var boardType = BoardType.UNKNOWN_BOARD

    private var xcService: MyService? = null

    private const val DBM_1 = -85
    private const val DBM_2 = -95
    private const val DBM_3 = -105
    private const val DBM_4 = -115
    private const val DBM_5 = -140

    fun setContext(context: Context?) {
        mContext = context
        val host = Build.HOST
        val user = Build.USER
        if (host.contains("ztlsz-") || host.contains("dell-")
            || user.contains("szdc") || user.contains("dell")) {
            boardType = BoardType.DC_BOARD
            if (mContext == null){
                throw NullPointerException("context不能为NULL")
            }
            ZtlManager.GetInstance().setContext(mContext!!.applicationContext)
        }else if (user.contains("xc") && host.contains("xc")){
            boardType = BoardType.XC_BOARD
            if (mContext == null){
                throw NullPointerException("context不能为NULL")
            }
            xcService = MyService(mContext)
        }
    }

    fun setBar(show: Boolean, appCompatActivity: AppCompatActivity?) {
        try {
            when (boardType) {
                BoardType.DC_BOARD -> ZtlManager.GetInstance().openSystemBar(show)
                BoardType.UNKNOWN_BOARD -> {}
                BoardType.XC_BOARD -> {
                    xcService?.hideNavBar = !show
                    xcService?.slideNavBar = false
                }
            }
        } catch (e: Exception) {
            Logger.e(e, "设置保活异常")
        }
    }

    private fun showBar(appCompatActivity: AppCompatActivity) {
        // 非全屏显示，显示状态栏和导航栏
        appCompatActivity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
    }

    private fun hideBar(appCompatActivity: AppCompatActivity) {

        //隐藏虚拟按键，并且全屏
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB && Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { // lower api
            val v = appCompatActivity.window.decorView
            v.systemUiVisibility = View.GONE
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //for new api versions.
            val decorView = appCompatActivity.window.decorView
            val uiOptions = (View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY or View.SYSTEM_UI_FLAG_FULLSCREEN)
            decorView.systemUiVisibility = uiOptions
        }
    }

    fun keepAlive() {
        try {
            val pkgName = mContext!!.packageName
            val aliveTime = 10
            when (boardType) {
                BoardType.UNKNOWN_BOARD -> {}
                BoardType.DC_BOARD -> ZtlManager.GetInstance().keepActivity(pkgName, aliveTime)
                BoardType.XC_BOARD -> xcService?.setAppListen(pkgName, aliveTime)
            }
        } catch (e: Exception) {
            Logger.e(e, "设置保活异常")
        }
    }

    fun cancelKeepAlive() {
        try {
            when (boardType) {
                BoardType.DC_BOARD -> ZtlManager.GetInstance().unKeepActivity()
                BoardType.UNKNOWN_BOARD -> {}
                BoardType.XC_BOARD -> xcService?.setAppListen("", 10)
            }
        } catch (e: Exception) {
            Logger.e(e, "取消保活异常")
        }
    }

    fun installApk(apkPath: String?) {
        try {
            if (apkPath == null) return
            if (!apkPath.endsWith(".apk")) return
            val apkFile = File(apkPath)
            if (apkFile.exists() && apkFile.isFile) {
                val pkgName = mContext!!.packageName
                when (boardType) {
                    BoardType.DC_BOARD -> ZtlManager.GetInstance().installAppAndStartUp(apkPath, pkgName)
                    BoardType.UNKNOWN_BOARD -> {}
                    BoardType.XC_BOARD -> xcService?.silentInstallApk(apkPath, pkgName, true)
                }
            }
        } catch (e: Exception) {
            Logger.e(e, "安装apk $apkPath 异常")
        }
    }

    fun getDeviceId(): String? {
        var devideId: String? = null
        try {
            devideId = when (boardType) {
                BoardType.DC_BOARD -> ZtlManager.GetInstance().deviceID
                BoardType.UNKNOWN_BOARD -> getCPUSerial()
                BoardType.XC_BOARD -> getCPUSerial()
            }
        } catch (e: Exception) {
            Logger.e(e, "获取设备ID异常")
        }
        return devideId
    }

    /**
     * 获取CPU序列号
     *
     * @return CPU序列号(16位)
     * 读取失败为"0000000000000000"
     */
    fun getCPUSerial(): String? {
        var str = ""
        var strCPU = ""
        var cpuAddress = "0000000000000000"
        var pp: Process? = null
        var ir: InputStreamReader? = null
        var input: LineNumberReader? = null
        try {
            //读取CPU信息
            pp = Runtime.getRuntime().exec("cat /proc/cpuinfo")
            ir = InputStreamReader(pp.inputStream)
            input = LineNumberReader(ir)

            //查找CPU序列号
            for (i in 1..99) {
                str = input.readLine()
                if (str != null) {

                    //查找到序列号所在行
                    if (str.indexOf("Serial") > -1) {

                        //提取序列号
                        strCPU = str.substring(str.indexOf(":") + 1, str.length)

                        //去空格
                        cpuAddress = strCPU.trim { it <= ' ' }
                        break
                    }
                } else {

                    //文件结尾
                    break
                }
            }
        } catch (ex: IOException) {

            //赋予默认值
            ex.printStackTrace()
        } finally {
            if (ir != null) {
                try {
                    ir.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
            if (input != null) {
                try {
                    input.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
            pp?.destroy()
        }
        return cpuAddress
    }

    @SuppressLint("NewApi", "MissingPermission")
    fun getIccid(): String? {
        val iccid: String?
        iccid = try {
            when (boardType) {
                BoardType.DC_BOARD -> ZtlManager.GetInstance().simIccid
                BoardType.UNKNOWN_BOARD -> getIccidDefault(mContext)
                BoardType.XC_BOARD -> getIccidDefault(mContext)
            }
        } catch (e: Exception) {
            ""
        }
        return iccid
    }

    /**
     * 获取iccid（普通方式）
     * @param context
     * @return
     */
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
    private fun getIccidDefault(context: Context?): String? {
        return try {
            var iccid1 = getICCId(context)
            if (iccid1.length < 20) {
                iccid1 = getIccidBySm(context)
            }
            if (iccid1.length < 20) {
                val iccid2 = getIccidByAt()
                if (iccid2.length == 20) {
                    return iccid2
                }
            }
            iccid1
        } catch (e: Exception) {
            e.printStackTrace()
            ""
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
    private fun getIccidBySm(context: Context?): String {
        var iccid = ""
        try {
            val sm =
                context!!.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE) as SubscriptionManager
            val sis = sm.activeSubscriptionInfoList
            for (subInfo in sis) {
//            Log.d("css","---------getIccId:" + subInfo.getIccId()); //ICC ID
                iccid = subInfo.iccId
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return iccid
    }

    /**
     * 通过AT指令获取iccid
     */
    private fun getIccidByAt(): String {
        val com = "/dev/ttyUSB2"
        Send(com, "at+ccid")
        return Receive(com)
    }

    private fun Send(file: String, cmd: String) {
        var localRandomAccessFile: RandomAccessFile? = null
        try {
            localRandomAccessFile = RandomAccessFile(file, "rw")
            localRandomAccessFile.writeBytes(cmd + "\r\n")
            localRandomAccessFile.close()
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            if (localRandomAccessFile != null) {
                try {
                    localRandomAccessFile.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
    }

    private fun Receive(file: String): String {
        var localRandomAccessFile: RandomAccessFile? = null
        var result = ""
        try {
            localRandomAccessFile = RandomAccessFile(file, "r")
            val arrayOfByte = ByteArray(1024)
            var readSize = 0
            while (localRandomAccessFile.read(arrayOfByte).also { readSize = it } == -1) {
            }
            val response = String(arrayOfByte).substring(0, readSize)
            result = response.substring(response.indexOf(":") + 2, response.indexOf(":") + 22)
            Log.e("DeviceInfo", "re:$response")
            Log.e(
                "DeviceInfo",
                "re:" + response.substring(response.indexOf(":") + 2, response.indexOf(":") + 22)
            )
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        } finally {
            if (localRandomAccessFile != null) {
                try {
                    localRandomAccessFile.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
        return result
    }

    /*
     * 获取ICCID
     * */
    private fun getICCId(context: Context?): String {
        val telephonyManager =
            context!!.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager // 取得相关系统服务
        return if (ActivityCompat.checkSelfPermission(
                context,
                Manifest.permission.READ_PHONE_STATE
            ) != PackageManager.PERMISSION_GRANTED
        ) {
            ""
        } else telephonyManager.simSerialNumber
        //取出 ICCID
    }

    fun rebootSystem() {
        try {
            when (boardType) {
                BoardType.DC_BOARD -> {
                    Log.d("BoardApiUtil", "定昌主板重启")
                    ZtlManager.GetInstance().reboot(1)
                }

                BoardType.UNKNOWN_BOARD -> try {
                    val proc = Runtime.getRuntime().exec(arrayOf("sh", "-c", "sync;reboot "))
                    proc.waitFor()
                } catch (ex: Exception) {
                    ex.printStackTrace()
                }

                BoardType.XC_BOARD -> xcService?.rebootSystem()
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Logger.e(e, "重启系统异常：" + e.message)
        }
    }

    fun installSilence(apkPath: String) {
        try {
            when (boardType) {
                BoardType.DC_BOARD -> {
                    Logger.e("定昌主板安装APK")
                    ZtlManager.GetInstance().installAppAndStartUp(apkPath, mContext!!.packageName)
                }

                BoardType.UNKNOWN_BOARD -> {
                    var process: Process? = null
                    var dataOutputStream: DataOutputStream? = null
                    var errorStream: BufferedReader? = null
                    try {
                        val file = File(apkPath)
                        if (!file.exists()) {
                            Logger.d("安装文件不存在：$apkPath")
                            return
                        }
                        //                        if (apkPath.contains("ZIAI")){
//                            context.sendBroadcast(new Intent("delaytowakeup"));
//                        }
                        Logger.d("开始安装APK：$apkPath")
                        // 申请su权限
                        process = Runtime.getRuntime().exec("su")
                        dataOutputStream = DataOutputStream(process.outputStream)
                        // 执行pm install命令
                        val command = "pm install -r $apkPath\n"
                        dataOutputStream.write(command.toByteArray(Charset.forName("utf-8")))
                        dataOutputStream.flush()
                        dataOutputStream.writeBytes("exit\n")
                        dataOutputStream.flush()
                        process.waitFor()
                        errorStream = BufferedReader(InputStreamReader(process.errorStream))
                        var msg = ""
                        var line: String
                        // 读取命令的执行结果
                        while (errorStream.readLine().also { line = it } != null) {
                            msg += line
                        }
                        Log.d("TAG", "install msg is $msg")
                        // 如果执行结果中包含Failure字样就认为是安装失败，否则就认为安装成功
//                        context.sendBroadcast(new Intent(Constants.FZS_INSTALL_REBOOT));
                    } catch (e: Exception) {
                        e.printStackTrace()
                    } finally {
                        if (dataOutputStream != null) {
                            try {
                                dataOutputStream.close()
                            } catch (e: IOException) {
                                e.printStackTrace()
                            }
                        }
                        if (errorStream != null) {
                            try {
                                errorStream.close()
                            } catch (e: IOException) {
                                e.printStackTrace()
                            }
                        }
                        process?.destroy()
                    }
                }

                BoardType.XC_BOARD -> xcService?.silentInstallApk(apkPath, mContext!!.packageName, true)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            Logger.e(e, "重启系统异常：" + e.message)
        }
    }

    fun isNetworkAvailable(): Boolean {
        return try {
            var netName = "UNKNOWN"
            val netWorkType = when (boardType) {
                BoardType.DC_BOARD -> ZtlManager.GetInstance().netWorkType
                BoardType.UNKNOWN_BOARD -> getNetWorkType(mContext)
                BoardType.XC_BOARD -> getNetWorkType(mContext)
            }
            when (netWorkType) {
                -1 -> netName = "UNKNOWN"
                0 -> netName = "ETHERNET"
                1 -> netName = "WIFI"
                2, 3, 4, 5 -> netName = "MOBILE"
            }
            if (netName == "UNKNOWN") {
                false
            } else true
        } catch (e: Exception) {
            false
        }
    }

    private fun getNetWorkType(context: Context?): Int {
        return if (context == null) {
            Log.e("上下文为空，不执行", "请检查是否已调用setContext()")
            -1
        } else {
            val ni = getNetworkInfo()
            if (ni == null) {
                -1
            } else if (ni.type == 9) {
                0
            } else if (ni.type == 1) {
                1
            } else {
                if (ni.type == 0) {
                    val nSubType = ni.subtype
                    val mTelephony = mContext!!.getSystemService("phone") as TelephonyManager
                    if (nSubType == 1 || nSubType == 2 || nSubType == 4 || nSubType == 16 && !mTelephony.isNetworkRoaming) {
                        return 2
                    }
                    if (nSubType == 3 || nSubType == 8 || nSubType == 5 && !mTelephony.isNetworkRoaming) {
                        return 3
                    }
                    if (nSubType == 13) {
                        return 4
                    }
                }
                -1
            }
        }
    }

    private fun getNetworkInfo(): NetworkInfo? {
        val mConnectivityManager =
            mContext!!.getSystemService("connectivity") as ConnectivityManager
        val mNetworkInfo = mConnectivityManager.activeNetworkInfo
        return if (mNetworkInfo != null && mNetworkInfo.isAvailable) mNetworkInfo else null
    }

    fun getDeviceNetSignal(): String {
        val netWorkType = getNetWorkType(mContext)
        var type = ""
        var signal = 0
        when (netWorkType) {
            0 -> //                netName = "ETHERNET";
            {
                type = "ETHERNET"
                signal = 100
            }
            1 -> //                netName = "WIFI";
            {
                type = "WIFI"
                signal = getWifiSignal()
            }

            2, 3, 4, 5 -> //                netName = "MOBILE";
            {
                type = "MOBILE"
                signal = getMobileDbm(mContext)
            }

            else -> {
                type = "OTHER"
                signal = getMobileDbm(mContext)
            }
        }
        return "$type,$signal"
    }

    private fun getWifiSignal(): Int {
        val wifi_service =
            mContext!!.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val wifiInfo = wifi_service.connectionInfo
        val sinal = wifiInfo.rssi
        Log.d("BoardApiUtil", "wifi信号值：" + (sinal + 100))
        //        int result = sinal + 120;
//        if (result < 0){
//            result = 0;
//        }
//        if (result > 100){
//            result = 100;
//        }
        return getWifiSignal(sinal)
    }

    /**
     * 获取手机信号强度，需添加权限 android.permission.ACCESS_COARSE_LOCATION <br></br>
     * API要求不低于17 <br></br>
     *
     * @return 当前手机主卡信号强度,单位 dBm（-1是默认值，表示获取失败）
     */
    private fun getMobileDbm(context: Context?): Int {
        var dbm = -1
        val tm = context!!.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        val cellInfoList: List<CellInfo>?
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            cellInfoList = tm.allCellInfo
            if (null != cellInfoList) {
                for (cellInfo in cellInfoList) {
                    if (cellInfo is CellInfoGsm) {
                        val cellSignalStrengthGsm = cellInfo.cellSignalStrength
                        dbm = cellSignalStrengthGsm.dbm
                    } else if (cellInfo is CellInfoCdma) {
                        val cellSignalStrengthCdma = cellInfo.cellSignalStrength
                        dbm = cellSignalStrengthCdma.dbm
                    } else if (cellInfo is CellInfoWcdma) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                            val cellSignalStrengthWcdma = cellInfo.cellSignalStrength
                            dbm = cellSignalStrengthWcdma.dbm
                        }
                    } else if (cellInfo is CellInfoLte) {
                        val cellSignalStrengthLte = cellInfo.cellSignalStrength
                        dbm = cellSignalStrengthLte.dbm
                    }
                }
            }
        }

//        dbm = dbm + 85;
//        if (dbm > 100){
//            dbm = 100;
//        }
//        if (dbm < 0){
//            dbm = 0;
//        }
        Log.d("BoardApiUtil", "信号值1：$dbm")
        return getSignal(dbm)
//        return setNetLevel(dbm);
    }

    /**
     * 1、当信号大于等于 - 85d Bm时候，信号显示满格
     * 2、当信号大于等于 - 95d Bm时候，而小于 - 85d Bm时，信号显示4格
     * 3、当信号大于等于 - 105d Bm时候，而小于 - 95d Bm时，信号显示3格，不好捕捉到。
     * 4、当信号大于等于 - 115d Bm时候，而小于 - 105d Bm时，信号显示2格，不好捕捉到。
     * 5、当信号大于等于 - 140d Bm时候，而小于 - 115d Bm时，信号显示1格，不好捕捉到。
     *
     * @param dbm
     */
    private fun setNetLevel(dbm: Int): Int {
        return if (dbm > DBM_1) {
            5
        } else if (DBM_2 < dbm && dbm < DBM_1) {
            4
        } else if (DBM_3 < dbm && dbm < DBM_2) {
            3
        } else if (DBM_4 < dbm && dbm < DBM_3) {
            2
        } else if (DBM_5 < dbm && dbm < DBM_4) {
            1
        } else {
            1
        }
    }

    private fun getSignal(s: Int): Int {
        var signal = Math.abs(s) - 85
        if (signal <= 0) {
            return 100
        }
        signal = 100 - signal * 3
        if (signal <= 0) {
            return 0
        }
        Log.d("BoardApiUtil", "信号值2：$signal")
        return signal
    }

    private fun getWifiSignal(s: Int): Int {
        var signal = Math.abs(s) - 30
        if (signal <= 0) {
            return 100
        }
        signal = 100 - signal * 1
        if (signal <= 0) {
            return 0
        }
        Log.d("BoardApiUtil", "信号值3：$signal")
        return signal
    }

    /**
     * 收集设备参数信息
     * @param context
     */
    fun getDeviceInfo(context: Context): Map<String, String>? {
        val infos: MutableMap<String, String> = HashMap()
        try {
            val pm = context.packageManager
            val pi = pm.getPackageInfo(context.packageName, PackageManager.GET_ACTIVITIES)
            if (pi != null) {
                val versionName = if (pi.versionName == null) "null" else pi.versionName
                val versionCode = pi.versionCode.toString() + ""
                infos["versionName"] = versionName
                infos["versionCode"] = versionCode
            }
        } catch (e: PackageManager.NameNotFoundException) {
            Log.e("getDeviceInfo", "an error occured when collect package info", e)
        }
        try {
            val fields = Build::class.java.declaredFields
            for (field in fields) {
                try {
                    field.isAccessible = true
                    infos[field.name] = field[null].toString()
                    Log.d("getDeviceInfo", field.name + " : " + field[null])
                } catch (e: Exception) {
                    Log.e("getDeviceInfo", "an error occured when collect crash info", e)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return infos
    }

    /**
     * [获取应用程序版本名称信息]
     * @param context
     * @return 当前应用的版本名称
     */
    @Synchronized
    fun getVersionName(context: Context): String? {
        try {
            val packageManager = context.packageManager
            val packageInfo = packageManager.getPackageInfo(
                context.packageName, 0
            )
            return packageInfo.versionName
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    @Synchronized
    fun getVersionCode(context: Context): Int {
        return try {
            val packageManager = context.packageManager
            val packageInfo = packageManager.getPackageInfo(
                context.packageName, 0
            )
            return packageInfo.versionCode
        } catch (e: Exception) {
            e.printStackTrace()
            -1
        }
    }

    fun getMacAddress(): String?{
        return when (boardType) {
            BoardType.DC_BOARD -> getMacAddressJar()
            BoardType.UNKNOWN_BOARD -> getMacAddressNormal()
            BoardType.XC_BOARD -> getMacAddressNormal()
        }
    }

    private fun getMacAddressJar(): String?{
        return ZtlManager.GetInstance().macAddress
    }

    private fun getMacAddressNormal(): String? {
        var str = ""
        var macSerial = ""
        try {
            val pp = Runtime.getRuntime().exec(
                "cat /sys/class/net/wlan0/address "
            )
            val ir = InputStreamReader(pp.inputStream)
            val input = LineNumberReader(ir)
            while (null != str) {
                str = input.readLine()
                if (str != null) {
                    macSerial = str.trim { it <= ' ' }
                    break
                }
            }
        } catch (ex: java.lang.Exception) {
            ex.printStackTrace()
        }
        if (macSerial == null || "" == macSerial) {
            try {
                return loadFileAsString("/sys/class/net/eth0/address")?.toUpperCase()?.substring(0, 17)
            } catch (e: java.lang.Exception) {
                e.printStackTrace()
            }
        }
        return macSerial
    }

    @Throws(java.lang.Exception::class)
    fun loadFileAsString(fileName: String?): String? {
        val reader = FileReader(fileName)
        val text = loadReaderAsString(reader)
        reader.close()
        return text
    }

    @Throws(java.lang.Exception::class)
    fun loadReaderAsString(reader: Reader): String {
        val builder = StringBuilder()
        val buffer = CharArray(4096)
        var readLength: Int = reader.read(buffer)
        while (readLength >= 0) {
            builder.append(buffer, 0, readLength)
            readLength = reader.read(buffer)
        }
        return builder.toString()
    }

    fun getNetworkType(): String{
        return try {
            var strNetworkType = ""
            val connectivity =
                mContext!!.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
            if (connectivity != null) {
                val networkInfo = connectivity.activeNetworkInfo
                if (networkInfo != null && networkInfo.isConnected) {
                    if (networkInfo.type == ConnectivityManager.TYPE_WIFI) {
                        strNetworkType = "WIFI"
                    } else if (networkInfo.type == ConnectivityManager.TYPE_MOBILE) {
                        val _strSubTypeName = networkInfo.subtypeName
                        Log.e("cocos2d-x", "Network getSubtypeName : $_strSubTypeName")

                        // TD-SCDMA   networkType is 17
                        val networkType = networkInfo.subtype
                        strNetworkType =
                            when (networkType) {
                                TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_EDGE, TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT, TelephonyManager.NETWORK_TYPE_IDEN -> "2G"
                                TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_HSDPA, TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_HSPA, TelephonyManager.NETWORK_TYPE_EVDO_B, TelephonyManager.NETWORK_TYPE_EHRPD, TelephonyManager.NETWORK_TYPE_HSPAP -> "3G"
                                TelephonyManager.NETWORK_TYPE_LTE -> "4G"
                                else ->                             // http://baike.baidu.com/item/TD-SCDMA 中国移动 联通 电信 三种3G制式
                                    if (_strSubTypeName.equals(
                                            "TD-SCDMA",
                                            ignoreCase = true
                                        ) || _strSubTypeName.equals(
                                            "WCDMA",
                                            ignoreCase = true
                                        ) || _strSubTypeName.equals("CDMA2000", ignoreCase = true)
                                    ) {
                                        "3G"
                                    } else {
                                        _strSubTypeName
                                    }
                            }
                        Log.e(
                            "cocos2d-x",
                            "Network getSubtype : " + Integer.valueOf(networkType).toString()
                        )
                    }
                }
                Log.e("cocos2d-x", "Network Type : $strNetworkType")
            }
            strNetworkType
        }catch (e: Exception){
            e.printStackTrace()
            logFile("获取网络类型异常：${e.message}")
            ""
        }

    }

    fun getNetIp(): String{
        return try {
            return when (boardType) {
                BoardType.DC_BOARD -> ZtlManager.GetInstance().localIpAddress
                BoardType.UNKNOWN_BOARD -> getIpNormal()
                BoardType.XC_BOARD -> getIpNormal()
            }
        }catch (e: Exception){
            "0.0.0.0"
        }
    }

    fun getMask(): String{
        return try {
            return when (boardType) {
                BoardType.DC_BOARD -> ZtlManager.GetInstance().localIpAddress
                BoardType.UNKNOWN_BOARD -> getIpNormal()
                BoardType.XC_BOARD -> getIpNormal()
            }
        }catch (e: Exception){
            "0.0.0.0"
        }
    }

    private fun getIpNormal(): String{
        try {
            //返回本机的所有接口，枚举类型;
            //至少包含一个元素，代表回路isLoopbackAddress;
            //只支持该机器内实体间能进行通信的接口
            //getNetworkInterfaces()+getInetAddresses()可以获取该节点的所有IP地址
            val networkInterfaceEnumeration = NetworkInterface.getNetworkInterfaces()
            //枚举进行遍历
            while (networkInterfaceEnumeration.hasMoreElements()) {
                val networkInterface = networkInterfaceEnumeration.nextElement()

                val inetAddressEnumeration = networkInterface.inetAddresses
                //枚举进行遍历
                while (inetAddressEnumeration.hasMoreElements()) {
                    val inetAddress = inetAddressEnumeration.nextElement()
                    //当不是回路地址且是IPV4时
                    if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
                        return inetAddress.getHostAddress()
                    }
                }
            }
        } catch (e: SocketException) {
            e.printStackTrace()
            return "0.0.0.0"
        }
        return "0.0.0.0"
    }


}